﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using VitCode.Castle.Entities;
using VitCode.ObjectResolutionHelper;

namespace VitCode.ObjectSettingApp
{
    public class BaseHelper
    {
        protected ClassRoleChecker m_Checker = new ClassRoleChecker();

        

        protected NameValueCollection m_DbTypeMapping;

        protected NameValueCollection m_ProLenMapping;

        protected StringCollection m_UniquePros;
        protected DataTable m_ColumnInfos;

        protected void InitInfo()
        {
            m_DbTypeMapping = GetDbTypeMapping();
            m_ProLenMapping = GetProLenMapping();
            m_UniquePros = GetUniquePro();
            m_ColumnInfos = GetDbColumnInfo();
        }

        

        protected string m_AssName;

        public const string CONN_STRING = "Data Source=192.168.1.11;Initial Catalog=CRS;User Id=sa;Password=vitcodesa";
        public const string ID = "Id",H_ID="HId";

        protected NameValueCollection GetDbTypeMapping()
        {
            var nvc = new NameValueCollection();
            var sr = new StreamReader("MappingFiles\\DbTypeMapping.txt");
            try
            {
                string str = sr.ReadToEnd();
                str = str.Replace("\r\n", "|");
                string[] ss = str.Split('|');
                foreach (string s in ss)
                {
                    string[] kvs = s.Split('=');
                    if (kvs.Length == 2)
                    {
                        string key = kvs[0];
                        string val = kvs[1];
                        if (string.IsNullOrEmpty(nvc.Get(key)))
                            nvc.Add(key, val);
                    }
                }
            }
            finally
            {
                sr.Close();
                sr.Dispose();
            }
            return nvc;
        }

        protected StringCollection GetUniquePro()
        {
            var sc = new StringCollection();
            var sr = new StreamReader("MappingFiles\\ProUniqueMapping.txt");
            try
            {
                string str = sr.ReadToEnd();
                str = str.Replace("\r\n", "|");
                string[] ss = str.Split('|');
                foreach (string s in ss)
                {
                    sc.Add(s);
                }
            }
            finally
            {
                sr.Close();
                sr.Dispose();
            }
            return sc;
        }

        protected NameValueCollection GetProLenMapping()
        {
            var nvc = new NameValueCollection();
            var sr = new StreamReader("MappingFiles\\ProLenMapping.txt");
            try
            {
                string str = sr.ReadToEnd();
                str = str.Replace("\r\n", "|");
                string[] ss = str.Split('|');
                foreach (string s in ss)
                {
                    string[] kvs = s.Split('=');
                    if (kvs.Length == 2)
                    {
                        string key = kvs[0];
                        string val = kvs[1];
                        if (string.IsNullOrEmpty(nvc.Get(key)))
                            nvc.Add(key, val);
                    }
                }
            }
            finally
            {
                sr.Close();
                sr.Dispose();
            }
            return nvc;
        }

        public DataTable GetDbColumnInfo()
        {
            var dt = new DataTable();
            var sql = "select o.Name TableName, c.Name ColumnName, t.Name TypeName, "
+ " CtlMaxLength=(case t.Name when 'nvarchar' then c.Max_length/2 when 'nchar' then c.Max_length/2 "
+ " when 'decimal' then 10 when 'tinyint' then 10 when 'smallint' then 10 "
+"  when 'int' then 10 when 'bigint' then 10 when 'datetime' then 20 else c.Max_Length end) "
+ " from sys.objects o inner join sys.columns c on c.object_id=o.object_id "
+ " and o.type='u' "
+ " inner join sys.types t on c.user_type_id=t.user_type_id";
            var cn = new SqlConnection(CONN_STRING);
            try
            {
                var da = new SqlDataAdapter(sql, cn);
                da.Fill(dt);
            }
            finally
            {
                cn.Close();
            }
            return dt;
        }


        public int GetProMaxLength(PropertyInfo p)
        {
            if (p == null) return 0;
            return GetProMaxLength(p.ReflectedType, p.Name);
        }

        public int GetProMaxLength(Type objType, string proName)
        {
            if (objType == null || string.IsNullOrEmpty(proName)) return 0;
            var sc = GetKeyProNames(objType);
            var assName = LookUpClassHelper.GetAssName(objType);
            string tableName = assName.Replace(".", "_") + "_" + objType.Name;
            DataRow[] rs =
                m_ColumnInfos.Select(DbColumnInfo.TABLE_NAME + "='" + tableName + "' and " +
                                     DbColumnInfo.COLUMN_NAME + "='" + proName + "'");
            if (rs.Length == 0)
                throw new ArgumentException("设置有问题,DB与Class的属性对应不上,TableName[" + tableName + "]ColumnName[" +
                                            proName + "],不存在");
            else if (rs.Length > 1)
                throw new ArgumentException("设置有问题,DB与Class的属性对应不上,TableName[" + tableName + "]ColumnName[" +
                                            proName + "],找到多个DB Field");
            string userMaxLen = Convert.ToString(rs[0][DbColumnInfo.MAX_LENGTH]);
            return Convert.ToInt32(userMaxLen);
        }
        

        public StringCollection GetSysProNames(Type objType)
        {
            var obj = Activator.CreateInstance(objType);
            var sc = new StringCollection();
            if (obj is BaseEntity)
                sc = ((BaseEntity)obj).GetSysProNames();
            return sc;
        }

        public StringCollection GetKeyProNames(Type objType)
        {
            var obj = Activator.CreateInstance(objType);
            var sc = new StringCollection();
            if (obj is BaseEntity)
                sc = ((BaseEntity)obj).GetKeyProNames();
            
                
            return sc;
        }

        public StringCollection GetNotCompareHisProNames(Type objType)
        {
            var obj = Activator.CreateInstance(objType);
            var sc = new StringCollection();
            if (obj is BaseEntity)
                sc = ((BaseEntity)obj).GetNotCompareHisProNames();
            return sc;
        }

        public string GetSqlListNodeXml(Type objType, bool isHisList)
        {
            var assName = LookUpClassHelper.GetAssName(objType);
            string tableName = assName.Replace(".", "_") + "_" + objType.Name;
            PropertyInfo[] pros = LookUpClassHelper.GetPros(objType);
            string sortExpress = "";
            var sqlSelectWords = new StringBuilder();
            foreach (PropertyInfo p in pros)
            {
                var strProDes = LookUpClassHelper.GetOrMemoDesValue(p);
                if (!p.CanWrite || string.IsNullOrEmpty(strProDes) || p.Name == HistoryKeyInfo.CURR_HIS_ID)
                    continue;

                if (p.PropertyType != typeof(Guid) && m_DbTypeMapping.Get(p.PropertyType.ToString()) != null)
                {
                    if (p.Name == "Name")
                        sortExpress = strProDes;
                    if(isHisList && p.Name == HistoryKeyInfo.H_VERSION_ID)
                        sqlSelectWords.Insert(0,",o." + p.Name + " " + LookUpClassHelper.GetOrMemoDesValue(p));
                    else
                        sqlSelectWords.Append(",o." + p.Name + " " + LookUpClassHelper.GetOrMemoDesValue(p));
                }
            }
            var dbKeyProName = "Id";
            var hBaseObjectId = "";
            if (isHisList)
            {
                sortExpress = "版本号 desc";
                dbKeyProName = "o.HId";
                hBaseObjectId = ",o.HBaseObjectId";
            }
            return ("\t\t<ListSql sql=\"select * from ( select "+dbKeyProName+hBaseObjectId+" " + sqlSelectWords + " from " + tableName +
                      " o ) a\" ctl_DataKeyField=\""+dbKeyProName+"\" ctl_AutoSort=\"True\" ctl_InitPageSize=\"15\" ctl_SortExpression=\"" +
                      sortExpress + "\" />\r\n");
        }

        
    }
}
